#include <QCoreApplication>
#include "qqdict.h"

QQDict::QQDict()
{
}

QQDict::~QQDict()
{
}

DictionaryDescription QQDict::getDescription()
{
    DictionaryDescription d;
    d.setName("QQ Online Dictionary");
    d.setShortName("qq dict en<->zh");
    d.setIcon(QIcon(":/icon.png"));
    d.setAbout("<html><body>QQ online dictionary is a free online service provided by Tencent .Inc China,"
               "It provides stable service and a well-defined Json API. "
               "This plugin is based on the free service of Tencent.<br>"
               "<b>Website:</b><br>"
               "<a href=\"http://dict.qq.com\">QQ online dictionary</a>"
               "</body></html>");
    //below infos current un-used.
    d.setFromLang(DictionaryDescription::English);
    d.setToLang(DictionaryDescription::English);
    d.setVersion("1.0");
    return d;
}

QList<QPair<QString, QString> > QQDict::getCandidateWords(QString key)
{
    Q_UNUSED(key);

    QList<QPair<QString, QString> > wordsList;
    return wordsList;
}

void QQDict::httpFinished()
{
    QByteArray b = reply->readAll();
    printf("%s\n", b.constData());
    if(QString(b).contains("\"sorry, no result")) {
        emit readyToShow("<b>sorry, no result</b>");
        return;
    }

    QString result = parseJson(QString::fromUtf8(b.constData()));
    emit readyToShow(result);
}

void QQDict::queryWord(QString key)
{
    QUrl url(QString("http://dict.qq.com/dict?q=%1").arg(key));
    reply = qnam.get(QNetworkRequest(url));
    connect(reply, SIGNAL(finished()),
            this, SLOT(httpFinished()));
    return;
/*
    connect(reply, SIGNAL(readyRead()),
            this, SLOT(httpReadyRead()));
    connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
            this, SLOT(updateDataReadProgress(qint64,qint64)));
*/

}


QString QQDict::parseJson(QString jsoncontent) {
    bool ok;
    JsonObject result = QtJson::parse(jsoncontent, ok).toMap();
    if (!ok) {
        //qFatal("An error occurred during parsing");
        return "";
    }

    QString lang = result["lang"].toString();
    if(lang.isEmpty() || lang.isNull())
        return "<b>sorry, no result</b>";
    //printf("LANG: %s\n", lang.toStdString().c_str());
    JsonArray local = result["local"].toList();
    if(local.size() == 0) {
        return "<b>sorry, no result</b>";
    }
    QStringList locallist;
    foreach(QVariant listitem,local) {
        QString string = QtJson::serializeStr(listitem);
        locallist << string;
    //    printf("%s\n", string.toStdString().c_str());
    }
    //only one for local tag.
    QString meaning = locallist.at(0);
    if(meaning.isEmpty() || meaning.isNull())
        return "<b>sorry, no result</b>";

    JsonObject obj = QtJson::parse(meaning, ok).toMap();

    //word
    QString word = obj["word"].toString(); 

    //pho
    QStringList pholist;
    JsonArray pho_arr = obj["pho"].toList();

    foreach(QVariant pho_i, pho_arr) {
        QString pho_str = QtJson::serializeStr(pho_i);
        pholist<<pho_str;
    }
    //lex and meaing.
    QList<QPair<QString, QString> > desList;    
    JsonArray des_arr = obj["des"].toList();
    foreach(QVariant des_i, des_arr) {
        QString des_str = QtJson::serializeStr(des_i);
        JsonObject des_obj = QtJson::parse(des_str, ok).toMap();
        QString lex = des_obj["p"].toString();
        QString des = des_obj["d"].toString();
        desList.append(QPair<QString, QString>(lex,des));
    }

    QStringList chdesList;
    if(lang == "ch") {
        JsonArray des_arr = obj["des"].toList();
        foreach(QVariant des_i, des_arr) {
            QString str = des_i.toString();
            chdesList<<str;
            //printf("%s\n",str.toStdString().c_str());
        }

        /*JsonArray des_arr = obj["des2"].toList();
        foreach(QVariant des_i, des_arr) {
            QString des_str = QtJson::serializeStr(des_i);
            JsonObject des_obj = QtJson::parse(des_str, ok).toMap();
            JsonArray des2_arr = des_obj["des"].toList();
            foreach(QVariant des2_i, des2_arr) {
                QString des2_str = QtJson::serialize(des2_i);
                JsonObject des2_obj = QtJson::parse(des2_str, ok).toMap();
                QString des = des2_obj["d"].toString();
                chdesList.append(des);
            }
        }*/
    }

    //example sentence
    QList<QPair<QString, QMap<QString, QString> > > senList;

    JsonArray sen_arr = obj["sen"].toList();
    foreach(QVariant sen_i, sen_arr) {
        QString sen_str = QtJson::serializeStr(sen_i);
        bool ok;
        JsonObject sen_obj = QtJson::parse(sen_str, ok).toMap();
        QString lex = sen_obj["p"].toString();

        JsonArray s_arr = sen_obj["s"].toList();
       
        QMap<QString, QString> senMap;
         
        foreach(QVariant s_i, s_arr) {
            QString s_str = QtJson::serializeStr(s_i);
            bool ok;
            JsonObject s_obj = QtJson::parse(s_str, ok).toMap();
            QString es_str = s_obj["es"].toString();

            QString cs_str = s_obj["cs"].toString();
            senMap.insert(es_str, cs_str);
        }
        senList.append(QPair<QString, QMap<QString, QString> >(lex, senMap));
    }

    //more 
    QList<QPair<QString, QString> > morList;
    JsonArray mor_arr = obj["mor"].toList();
    foreach(QVariant mor_i, mor_arr) {
        QString mor_str = QtJson::serializeStr(mor_i);
        bool ok;
        JsonObject mor_obj = QtJson::parse(mor_str, ok).toMap();
        QString c_str = mor_obj["c"].toString();
        QString m_str = mor_obj["m"].toString();
        morList.append(QPair<QString, QString>(c_str, m_str));
    }

    //syn
    QList<QPair<QString, QStringList > > synList;

    JsonArray syn_arr = obj["syn"].toList();
    foreach(QVariant syn_i, syn_arr) {
        QString syn_str = QtJson::serializeStr(syn_i);
        bool ok;
        JsonObject syn_obj = QtJson::parse(syn_str, ok).toMap();
        QString lex = syn_obj["p"].toString();

        JsonArray s_arr = syn_obj["c"].toList();

        QStringList strlist;

        foreach(QVariant s_i, s_arr) {
            QString str = s_i.toString(); 
            strlist.append(str);
        }
        synList.append(QPair<QString, QStringList>(lex, strlist));
    }

    //ant
    QList<QPair<QString, QStringList > > antList;

    JsonArray ant_arr = obj["ant"].toList();
    foreach(QVariant ant_i, ant_arr) {
        QString ant_str = QtJson::serializeStr(ant_i);
        bool ok;
        JsonObject ant_obj = QtJson::parse(ant_str, ok).toMap();
        QString lex = ant_obj["p"].toString();

        JsonArray s_arr = ant_obj["c"].toList();

        QStringList strlist;

        foreach(QVariant s_i, s_arr) {
            QString str = s_i.toString(); 
            strlist.append(str);
        }
        antList.append(QPair<QString, QStringList>(lex, strlist));
    }


    //phrase
    QList<QPair<QString, QString> > phsList;
    JsonArray phs_arr = obj["ph"].toList();
    foreach(QVariant phs_i, phs_arr) {
        QString phslist_str = QtJson::serializeStr(phs_i);
        bool ok;
        JsonObject phs_obj = QtJson::parse(phslist_str, ok).toMap();
        QString phs_str = phs_obj["phs"].toString();
        QString phd_str = phs_obj["phd"].toString();
        phsList.append(QPair<QString, QString>(phs_str, phd_str));
    }


/*
    printf("word: %s\n", word.toStdString().c_str());

    for(int i = 0; i < pholist.size(); i++)
        printf("pho: %s\n", pholist.at(i).toStdString().c_str());

    for(int i = 0; i < morList.size(); i++) {
        printf("c: %s m: %s\n", morList.at(i).first.toStdString().c_str(), morList.at(i).second.toStdString().c_str());
    }
    for(int i = 0; i < desList.size(); i++) {
        printf("lex: %s des: %s\n", desList.at(i).first.toStdString().c_str(), desList.at(i).second.toStdString().c_str());
    }

    for(int i = 0; i < senList.size(); i++) {
        printf("lex: %s\n", senList.at(i).first.toStdString().c_str());
        QMap<QString, QString> senM = senList.at(i).second;
        QMapIterator<QString, QString> mi(senM);
        while (mi.hasNext()) {
            mi.next();
            printf("\ten: %s\n\tzh: %s\n", mi.key().toStdString().c_str(), mi.value().toStdString().c_str());
        }
    }

    for(int i = 0; i < synList.size(); i++) {
        printf("lex: %s\n", synList.at(i).first.toStdString().c_str());
        QStringList tl = synList.at(i).second;
        for(int j = 0; j < tl.size(); j++) {
            printf("%s ", tl.at(j).toStdString().c_str());
        } 
        printf("\n");
    }
    for(int i = 0; i < antList.size(); i++) {
        printf("lex: %s\n", antList.at(i).first.toStdString().c_str());
        QStringList tl = antList.at(i).second;
        for(int j = 0; j < tl.size(); j++) {
            printf("%s ", tl.at(j).toStdString().c_str());
        } 
        printf("\n");
    }

    for(int i = 0; i < phsList.size(); i++) {
        printf("phs: %s phd: %s\n", phsList.at(i).first.toStdString().c_str(), phsList.at(i).second.toStdString().c_str());
    }
*/
    QString html;
    html += "<html><head><meta name=\"qrichtext\" content=\"text/html;charset=UTF-8\"/><body style=\"font-size:10pt\">";

    //word
    html += "<span style=\"font-size: 12pt; color:#0000ff;\"><b>"+ word +"</b></span>&nbsp;";

    //phonetic
    for(int i = 0; i < pholist.size(); i++)
        html += QString(pholist.at(i)).replace("\"","/")+"&nbsp;";
    html += "<br><p>";

    if(lang == "eng") {
        //mor
        for(int i = 0; i < morList.size(); i++) {
            html += morList.at(i).first
                    + "&nbsp;<span style=\"color: #00aa00\">"
                    + morList.at(i).second + "</span>&nbsp;&nbsp;";
        }
        html += "</p>";

        html += "<p>";
        //basic meaning and example sentence
        for(int i = 0; i < desList.size(); i++) {
            QString lex = desList.at(i).first;
            html += "<br><span style=\"font-style:italic; color:#ff007f;\">"
                    + lex + "</span>";
            html += "&nbsp;<b>"+desList.at(i).second+"</b><br><br>";
            for(int i = 0; i < senList.size(); i++) {
                if(senList.at(i).first == lex) {
                    QMap<QString, QString> senM = senList.at(i).second;
                    QMapIterator<QString, QString> mi(senM);
                    while (mi.hasNext()) {
                        mi.next();
                        html += "<span style=\"color: #4d4d4d;\">&nbsp;&nbsp;&nbsp;&nbsp;" + QString::fromUtf8("•") + mi.key() + "<br>";
                        html += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + mi.value() + "<br></span>";
                    }
                }
            }
            //printf("lex: %s des: %s\n", desList.at(i).first.toStdString().c_str(), desList.at(i).second.toStdString().c_str());
        }

        html += "</p>";

        //phrase
        if(phsList.size() > 0)
            html += "<p><span style=\"color: #00007f\"><b>"+tr("Phrase")+"</b></span></p>";

        for(int i = 0; i < phsList.size(); i++) {
            QString phrase = phsList.at(i).first;
            QString meaning = phsList.at(i).second;
            html += QString("<a href=\"query://%1\">").arg(phrase.toLower().simplified().replace(" ", "_"))
                    + phrase + "</a>"+ "&nbsp;&nbsp;<span style=\"color: #4d4d4d;\">" + meaning + "</span><br>";
        }
    }

    if(lang == "ch") {
        for(int i =0; i < chdesList.size(); i++) {
            html += "<span style=\"color: #4d4d4d;\">"
                    + QString::fromUtf8(chdesList.at(i).toLatin1().constData())
                    +"</span><br>";
        }
    }

    html += "</body></html>";
    return html;
}

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#else
Q_EXPORT_PLUGIN2(qqdict, QQDict);
#endif
